package pkg

import (
	"fmt"
	"gitee.com/wayjin/fabric-extension/gateway"
	"github.com/gin-gonic/gin"
	"strconv"
)


type ChannelRequest struct {
	OrgName  string `form:"orgName" binding:"required"`
	PeerID   string `form:"peer" binding:"required"`
	Username string `form:"username" binding:"required"`
	UserPwd  string `form:"secret"`
}

func createChannel(svc Service, ctx *gin.Context) {

}

func joinChannel(svc Service, ctx *gin.Context) {

}

func listChannel(svc Service, ctx *gin.Context) Response {
	var req ChannelRequest
	err := ctx.ShouldBind(&req)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error(), "message": "parse request fail"})
		return ResponseError(500, err)
	}
	peerCtx, err := svc.getPeerContext(req.OrgName, req.PeerID)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	mspid, err := svc.getMSPID(req.OrgName)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	suite, err := svc.getCryptoSuite(mspid, req.Username, []byte(req.UserPwd))
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}

	channels, err := gateway.ListChannels(suite, peerCtx)
	if err != nil {
		// ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	//ctx.JSON(200, gin.H{"channels": channels})
	return ResponseSuccess(channels)
}

func getBlockChainInfo(svc Service, ctx *gin.Context) Response {
	channelID := ctx.Param("channelid")
	if channelID == "" {
		//ctx.JSON(400, gin.H{"error": "channel id is required"})
		return ResponseError(400, fmt.Errorf("channel is is missing"))
	}
	var req ChannelRequest
	err := ctx.ShouldBind(&req)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}

	peerCtx, err := svc.getPeerContext(req.OrgName, req.PeerID)
	if err != nil {
		return ResponseError(500, err)
	}
	mspid, err := svc.getMSPID(req.OrgName)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	suite, err := svc.getCryptoSuite(mspid, req.Username, []byte(req.UserPwd))
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}

	blockChain, err := gateway.GetChannelInfo(suite, channelID, peerCtx)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	//ctx.JSON(200, gin.H{"blockchain": blockChain})
	return ResponseSuccess(blockChain)
}

func getBlock(svc Service, ctx *gin.Context) Response {
	number := ctx.Param("number")
	blockNum, err := strconv.ParseInt(number, 10, 64)
	if err != nil {
		//ctx.JSON(400, err)
		return ResponseError(400, err)
	}
	fmt.Println("blockNumber:", blockNum)
	channelid := ctx.Param("channelid")
	if channelid == "" {
		//ctx.JSON(400, gin.H{"error": "channel id is required"})
		return ResponseError(400, fmt.Errorf("channel id is missing"))
	}
	ordererCtx, err := svc.getDefaultOrderer()
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	var req ChannelRequest
	err = ctx.ShouldBind(&req)
	if err != nil {
		// ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	mspid, err := svc.getMSPID(req.OrgName)
	if err != nil {
		// ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	suite, err := svc.getCryptoSuite(mspid, req.Username, []byte(req.UserPwd))
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}

	block, err := gateway.GetBlock(suite, channelid, ordererCtx, uint64(blockNum))
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	// ctx.JSON(200, block)
	return ResponseSuccess(block)
}

func listBlocks(svc Service, ctx *gin.Context) Response {
	channelid := ctx.Param("channelid")
	if channelid == "" {
		//ctx.JSON(400, gin.H{"error": "channel id is required"})
		return ResponseError(400, fmt.Errorf("channel id is missing"))
	}
	count := ctx.Param("count")
	topCount, err := strconv.ParseInt(count, 10, 64)
	if err != nil {
		//ctx.JSON(400, err)
		return ResponseError(400, err)
	}

	var req ChannelRequest
	err = ctx.ShouldBind(&req)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	mspid, err := svc.getMSPID(req.OrgName)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	suite, err := svc.getCryptoSuite(mspid, req.Username, []byte(req.UserPwd))
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}

	ordererCtx, _ := svc.getDefaultOrderer()
	blocks, err := gateway.GetTopCountBlocks(suite, channelid, uint64(topCount), ordererCtx)
	if err != nil {
		//ctx.JSON(500, gin.H{"error": err.Error()})
		return ResponseError(500, err)
	}
	// ctx.JSON(200, gin.H{"blocks": blocks})
	return ResponseSuccess(blocks)
}